import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:largefriends/entity/entities/chat_new_message_entity.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/sticker_helper.dart';
import 'package:largefriends/pages/lf_payment/lf_payment_logic.dart';
import 'package:largefriends/res/lf_color.dart';
import 'package:largefriends/res/lf_double_ext.dart';
import 'package:largefriends/res/lf_fonts.dart';
import 'package:largefriends/res/lf_string_ext.dart';
import 'package:largefriends/service/lf_auth_service.dart';
import 'package:path/path.dart' as _path;
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:record/record.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';

import '../../../service/manager/lf_store_helper.dart';
import '../../../res.dart';
import '../../../res/lf_text_style.dart';
import '../../../res/lf_widget_ext.dart';
import '../../../res/strings/lf_strings.dart';
import '../../../utils/lf_keyboard.dart';
import '../../../utils/lf_scroll_behavior.dart';
import '../../../widgets/dialog_action_tip.dart';
import '../../../widgets/keyboard_height.dart';
import '../../../widgets/lf_image_picker.dart';

enum BottomType {
  empty,
  normal;
}

class LfChatBottom extends StatefulWidget {
  final BottomType type;
  final Rx<ChatNewMessageEntity?>? replyMessage;
  final RxBool isCanChat;
  final RxBool isShowSticker;
  final RxBool isShowAudio;
  final Function()? startRecord;
  final Function(File file, int duration)? sendRecordMessage;
  final Function(String value)? sendStickerMessage;
  final Function(String message)? sendTextMessage;
  final Function(AssetEntity file)? sendImageMessage;
  final FocusNode focusNode;
  final TextEditingController textEditingController;
  const LfChatBottom({
    Key? key,
    required this.type,
    this.replyMessage,
    required this.isCanChat,
    required this.isShowSticker,
    required this.isShowAudio,
    this.startRecord,
    this.sendRecordMessage,
    this.sendStickerMessage,
    this.sendTextMessage,
    this.sendImageMessage,
    required this.focusNode,
    required this.textEditingController,
  }) : super(key: key);

  @override
  _LfChatBottomState createState() {
    return _LfChatBottomState();
  }
}

class _LfChatBottomState extends State<LfChatBottom>
    with
        WidgetsBindingObserver,
        KeyboardHeight,
        SingleTickerProviderStateMixin {
  RxString inputMessage = ''.obs;
  AudioRecorder? recordPlugin;
  Timer? _timer;

  final RxInt _count = 0.obs;
  var keyboardVisibilityController = KeyboardVisibilityController();
  LfAuthService authService = Get.find();
  @override
  void initState() {
    super.initState();

    recordPlugin = AudioRecorder();

    recordPlugin?.onStateChanged().listen((event) {});
    keyboardVisibilityController.onChange.listen((event) {
      if (event == true) {
        Future.delayed(const Duration(milliseconds: 400), () {
          widget.isShowSticker.value = false;
          widget.isShowAudio.value = false;
        });
      }
    });
  }

  @override
  void dispose() {
    overlayEntry?.remove();
    overlayEntry = null;
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (widget.type == BottomType.normal) {
      return KeyboardVisibilityProvider(
          controller: keyboardVisibilityController, child: inputWidget());
    }
    return empty;
  }

  Widget inputWidget() {
    return Material(
      elevation: 10,
      color: color8F8F8F,
      child: Column(
        children: [
          Obx(() {
            return Visibility(
              visible: widget.replyMessage?.value != null,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  10.h.sbh,
                  Row(
                    children: [
                      10.w.sbw,
                      Text(
                        '${strRetry.tr}: ',
                        style: lfTextStyle(
                            sp: 14.sp,
                            fontFamily: fontMedium,
                            color: color210215),
                      ),
                      Expanded(
                          child: Text(
                        widget.replyMessage?.value?.message?.replaceBreak ?? "",
                        textWidthBasis: TextWidthBasis.longestLine,
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                        style: lfTextStyle(
                            sp: 13.sp,
                            fontFamily: fontRegular,
                            color: color210215),
                      )),
                      InkWell(
                        child: Padding(
                          padding: EdgeInsets.symmetric(horizontal: 10.w),
                          child: Icon(
                            Icons.cancel_outlined,
                            color: color210215,
                            size: 22.r,
                          ),
                        ),
                        onTap: () {
                          widget.replyMessage?.value = null;
                        },
                      )
                    ],
                  ),
                ],
              ),
            );
          }),
          Row(
            children: [
              InkWell(
                child: Padding(
                  padding: EdgeInsets.only(left: 10.w, right: 10.w),
                  child: Image.asset(
                    Res.ic_voice,
                    width: 32.r,
                    color: colorFEFEFE,
                  ),
                ),
                onTap: () async {
                  var microphonePermission =
                      await Permission.microphone.request();
                  if (microphonePermission == PermissionStatus.granted ||
                      microphonePermission == PermissionStatus.provisional) {
                  } else {
                    showActionTips(
                        tips: strRecordMicrophoneTip.tr,
                        actionButtonTip: strContinue.tr,
                        action: () {
                          openAppSettings();
                        });
                    return;
                  }
                  var recordPermission = await recordPlugin?.hasPermission();
                  if (recordPermission == false) {
                    showActionTips(
                        tips: strRecordMicrophoneTip.tr,
                        actionButtonTip: strContinue.tr,
                        action: () {
                          closeSoftKeyboard();
                          openAppSettings();
                        });
                    return;
                  }
                  widget.isShowSticker.value = false;
                  if (authService.currentAccount!.isGold() ||
                      widget.isCanChat.isTrue) {
                    widget.isShowAudio.value = !widget.isShowAudio.value;
                  } else {
                    widget.isShowAudio.value = false;
                    closeSoftKeyboard();
                    toPayment();
                    return;
                  }
                  if (widget.isShowAudio.isFalse) {
                    Future.delayed(const Duration(milliseconds: 300), () {
                      showSoftKeyboard(widget.focusNode);
                    });
                  } else {
                    closeSoftKeyboard();
                  }
                },
              ),
              Expanded(child: _textFieldWidget()),
              InkWell(
                  child: Padding(
                    padding: EdgeInsets.only(left: 10.w),
                    child: Image.asset(
                      Res.ic_emoji,
                      width: 32.r,
                      color: colorFEFEFE,
                    ),
                  ),
                  onTap: () async {
                    closeSoftKeyboard();
                    widget.isShowAudio.value = false;
                    widget.isShowSticker.value = !widget.isShowSticker.value;
                  }),
              InkWell(
                child: Padding(
                  padding: EdgeInsets.only(left: 10.w, right: 10.w),
                  child: Obx(() {
                    if (inputMessage.trim().isEmpty) {
                      return Icon(
                        Icons.photo,
                        size: 32.r,
                        color: colorFEFEFE,
                      );
                    } else {
                      return Container(
                        decoration: BoxDecoration(
                            color: colorFEFEFE, borderRadius: 6.r.radius),
                        padding: EdgeInsets.symmetric(
                            horizontal: 6.w, vertical: 4.h),
                        child: Text(
                          strSend.tr.toUpperCase(),
                          style: lfTextStyle(
                              sp: 16.sp,
                              fontFamily: fontRegular,
                              color: color000000),
                        ),
                      );
                    }
                  }),
                ),
                onTap: () {
                  if (inputMessage.trim().isEmpty) {
                    sendImageMessage();
                  } else {
                    sendTextMessage();
                  }
                },
              ),
            ],
          ),
          _frameWidget(),
        ],
      ),
    );
  }

  Widget _textFieldWidget() {
    return TextField(
      focusNode: widget.focusNode,
      controller: widget.textEditingController,
      minLines: 1,
      maxLines: 4,
      textInputAction: TextInputAction.send,
      inputFormatters: [
        LengthLimitingTextInputFormatter(500),
      ],
      textCapitalization: TextCapitalization.sentences,
      keyboardType: TextInputType.text,
      cursorColor: colorFEFEFE,
      style: lfTextStyle(sp: 16.sp, fontFamily: fontRegular),
      onSubmitted: (value) {
        sendTextMessage();
      },
      // AppTextStyles.appRegularTextStyle,
      decoration: InputDecoration(
        isCollapsed: true,
        contentPadding: EdgeInsets.symmetric(vertical: 16.h),
        border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(2.r),
            borderSide: const BorderSide(
              style: BorderStyle.solid,
              color: Colors.transparent,
              width: 0.8,
            ),
            gapPadding: 0),
        enabledBorder: OutlineInputBorder(
            borderRadius: BorderRadius.circular(2.r),
            borderSide: const BorderSide(
              style: BorderStyle.solid,
              color: Colors.transparent,
              width: 0.8,
            ),
            gapPadding: 0),
        focusedBorder: OutlineInputBorder(
            borderRadius: BorderRadius.circular(2.r),
            borderSide: const BorderSide(
              style: BorderStyle.solid,
              color: Colors.transparent,
              width: 0.8,
            ),
            gapPadding: 0),
        disabledBorder: OutlineInputBorder(
            borderRadius: BorderRadius.circular(2.r),
            borderSide: const BorderSide(
              style: BorderStyle.solid,
              color: Colors.transparent,
              width: 0.8,
            ),
            gapPadding: 0),
        filled: false,
        // fillColor: AppColors.modelGrayColor,
        hintText: strWriteMessage.tr,
        hintStyle:
            lfTextStyle(sp: 16.sp, fontFamily: fontRegular, color: color514F62),
      ),
      onEditingComplete: () {},
      onChanged: (vale) {
        inputMessage.value = vale;
      },
    );
  }

  Widget _frameWidget() {
    return Obx(() {
      double height = _getDefaultKeyBoardHeight() - _keyboardHeight.value;
      if (widget.isShowAudio.isFalse && widget.isShowSticker.isFalse) {
        return empty;
      }
      return Container(
        height: height,
        alignment: Alignment.center,
        child: widget.isShowAudio.isFalse ? _emojiWidget() : _voiceWidget(),
      );
    });
  }

  Widget _emojiWidget() {
    var list = stickerAnim.entries.toList();
    return Padding(
      padding: EdgeInsets.symmetric(horizontal: 10.w),
      child: ScrollConfiguration(
          behavior: LfScrollBehavior(),
          child: CustomScrollView(
            slivers: [
              10.h.sliverBox,
              SliverGrid.builder(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 5,
                    mainAxisSpacing: 10.w,
                    crossAxisSpacing: 10.w),
                itemBuilder: (context, index) {
                  var entity = list[index];
                  return InkWell(
                    child: Image.asset(entity.value),
                    onTap: () {
                      if (widget.isCanChat.value == true) {
                        widget.sendStickerMessage?.call(entity.key);
                      } else if (authService.currentAccount?.isGold() != true) {
                        closeSoftKeyboard();
                        toPayment();
                      }
                    },
                  );
                },
                itemCount: list.length,
              ),
              10.h.sliverBox,
            ],
          )),
    );
  }

  OverlayEntry? overlayEntry;
  RxInt recordState = 0.obs;
  Widget _voiceWidget() {
    return CustomScrollView(
      slivers: [
        15.h.sliverBox,
        Center(
          child: Obx(() {
            var tips = strHoldToRecord.tr;
            if (recordState.value == 1) {
              tips = strReleaseToSend.tr;
            } else if (recordState.value == 2) {
              tips = strReleaseToCancel.tr;
            }
            return Text(
              tips,
              style: lfTextStyle(
                  sp: 16.sp,
                  fontFamily: fontMedium,
                  color: recordState.value == 2 ? colorFF007F : colorFEFEFE),
              textAlign: TextAlign.center,
            );
          }),
        ).sliverBox,
        Center(
          child: Padding(
            padding: EdgeInsets.symmetric(vertical: 10.h),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Container(
                  decoration:
                      BoxDecoration(color: colorFEFEFE, shape: BoxShape.circle),
                  width: 12.r,
                  height: 12.r,
                ),
                5.w.sbw,
                Obx(() {
                  var text = '';
                  var duration = _count.value;
                  if (duration < 10) {
                    text = '00:0$duration';
                  } else if (duration >= 10 && duration < 50) {
                    text = '00:$duration';
                  } else {
                    // text = '${strRecordingWillStop.tr} ${60 - duration}"';
                    text = strRecordingWillStop.tr
                            .replacePercentS(["${60 - duration}"]) ??
                        "";
                  }
                  return Text(
                    text,
                    style: lfTextStyle(
                        sp: 14.sp, fontFamily: fontMedium, color: colorFEFEFE),
                  );
                })
              ],
            ),
          ),
        ).sliverBox,
        8.h.sliverBox,
        GestureDetector(
          child: Obx(() {
            if (recordState.value == 1) {
              return Container(
                height: 125.r,
                width: 125.r,
                alignment: Alignment.center,
                child: Container(
                  clipBehavior: Clip.hardEdge,
                  decoration: BoxDecoration(
                    color: colorFEFEFE,
                    shape: BoxShape.circle,
                    boxShadow: [
                      BoxShadow(
                        color: colorFEFEFE.withOpacity(0.3),
                        blurRadius: 15.0,
                        spreadRadius: 6.0,
                        offset: const Offset(0, 8),
                      ),
                      BoxShadow(
                        color: colorFEFEFE.withOpacity(0.3),
                        blurRadius: 15.0,
                        spreadRadius: 6.0,
                        offset: const Offset(0, -8),
                      ),
                      BoxShadow(
                        color: colorFEFEFE.withOpacity(0.3),
                        blurRadius: 15.0,
                        spreadRadius: 6.0,
                        offset: const Offset(-8, 0),
                      ),
                      BoxShadow(
                        color: colorFEFEFE.withOpacity(0.3),
                        blurRadius: 15.0,
                        spreadRadius: 6.0,
                        offset: const Offset(8, 0),
                      ),
                    ],
                  ),
                  height: 100.r,
                  width: 100.r,
                  alignment: Alignment.center,
                  child: Image.asset(
                    Res.chat_voice_icon,
                    width: 40.w,
                  ),
                ),
              );
            }
            return Container(
              height: 125.r,
              width: 125.r,
              clipBehavior: Clip.hardEdge,
              decoration:
                  BoxDecoration(color: colorFEFEFE, shape: BoxShape.circle),
              alignment: Alignment.center,
              child: Image.asset(
                Res.chat_voice_icon,
                width: 40.w,
                color: color000000,
              ),
            );
          }),
          onLongPressStart: (details) async {
            var microphonePermission = await Permission.microphone.request();
            var recordPermission = await recordPlugin?.hasPermission();
            if (!(microphonePermission.isGranted) ||
                (recordPermission == false)) {
              return;
            } else {
              _count.value = 0;
              _timer = Timer.periodic(const Duration(milliseconds: 1000), (t) {
                _count.value = _count.value + 1;
                if (_count.value == 60) {
                  _hideOverlay();
                }
              });
              // await controller.stopPlayAudio();
              widget.startRecord?.call();
              _buildOverLayView();
              const config = RecordConfig(encoder: AudioEncoder.aacLc);
              var path = await _getPath();
              await recordPlugin?.start(config, path: path);
            }
            recordState.value = 1;
          },
          onLongPressMoveUpdate: (value) {
            if (value.localOffsetFromOrigin.dy < -150) {
              recordState.value = 2;
            } else {
              recordState.value = 1;
            }
          },
          onLongPressEnd: (details) {
            _hideOverlay();
          },
        ).sliverBox,
      ],
    );
  }

  Future<String> _getPath() async {
    final dir = await getApplicationDocumentsDirectory();
    return _path.join(
      dir.path,
      'audio_${DateTime.now().millisecondsSinceEpoch}.m4a',
    );
  }

  _hideOverlay() async {
    if (overlayEntry != null) {
      overlayEntry?.remove();
      overlayEntry = null;
    }
    _timer?.cancel();

    int duration = _count.value;
    _count.value = 0;
    var path = await recordPlugin?.stop();
    if (path.isNullOrEmpty == false && duration > 1 && recordState.value != 2) {
      var file = File(path!);
      var isExist = await file.exists();
      if (isExist) {
        widget.sendRecordMessage?.call(file, duration);
      }
    }
    recordState.value = 0;
  }

  _buildOverLayView() {
    if (overlayEntry == null) {
      overlayEntry = OverlayEntry(builder: (content) {
        return Container(
          width: ScreenUtil().screenWidth,
          height: ScreenUtil().screenHeight,
          color: Colors.transparent,
        );
      });
      Overlay.of(context).insert(overlayEntry!);
    } else {
      Overlay.of(Get.context!).insert(overlayEntry!);
    }
  }

  void sendTextMessage() {
    if (widget.isCanChat.value == true) {
      if (inputMessage.value.trim().isNotEmpty) {
        widget.sendTextMessage?.call(inputMessage.value.trim());
        inputMessage.value = '';
      }
    } else if (authService.currentAccount!.isGold() != true) {
      closeSoftKeyboard();
      toPayment();
    }
  }

  void sendImageMessage() {
    closeSoftKeyboard();
    widget.isShowSticker.value = false;
    widget.isShowAudio.value = false;
    if (widget.isCanChat.value == true) {
      LfImagePicker.pickerImage((result) {
        if (result.isNotEmpty) {
          widget.sendImageMessage?.call(result.first);
        }
      });
    } else if (authService.currentAccount!.isGold() != true) {
      closeSoftKeyboard();
      toPayment();
    }
  }

  double _defaultKeyboardHeight =
      LfStorageManager.getDouble('key_keyboard_height') ?? 200;
  final RxDouble _keyboardHeight = 0.0.obs;

  _getDefaultKeyBoardHeight() {
    if (_defaultKeyboardHeight == 200) {
      _defaultKeyboardHeight =
          LfStorageManager.getDouble('key_keyboard_height') ?? 200;
    }
    return _defaultKeyboardHeight;
  }

  @override
  void keyboardHeight(double height) {
    _keyboardHeight.value = height;
    super.keyboardHeight(height);
  }
}
